import React, { useId, useRef, useState } from 'react';

import ReactCrop, {
  type Crop,
  centerCrop,
  convertToPixelCrop,
  makeAspectCrop,
  type PixelCrop,
} from 'react-image-crop';
import { canvasPreview } from './canvasPreview';
import { useDebounceEffect } from './useDebounceEffect';

import 'react-image-crop/dist/ReactCrop.css';
import { UploadOutlined } from '@ant-design/icons';
import { Button, Col, Modal, Radio, Row, Slider } from 'antd';
import { gutter } from '@/pages/const/keys';
import styles from './index.modules.less';

// This is to demonstate how to make and center a % aspect crop
// which is a bit trickier so we use some helper functions.
function centerAspectCrop(
  mediaWidth: number,
  mediaHeight: number,
  aspect: number,
) {
  return centerCrop(
    makeAspectCrop(
      {
        unit: '%',
        width: 100,
      },
      aspect,
      mediaWidth,
      mediaHeight,
    ),
    mediaWidth,
    mediaHeight,
  );
}
type Props = {
  //上传中
  uploading: boolean;
  onOk?: (dataUrl: string, blob: Blob) => void;
};
export default function App(props: Props) {
  const { uploading, onOk = () => {} } = props;
  const fileRef = useRef<HTMLInputElement>(null);
  const [random, setRandom] = useState(0);
  const [show, setShow] = useState(false);
  const [imgSrc, setImgSrc] = useState('');
  const previewCanvasRef = useRef<HTMLCanvasElement>(null);
  const imgRef = useRef<HTMLImageElement>(null);
  const hiddenAnchorRef = useRef<HTMLAnchorElement>(null);
  // const blobUrlRef = useRef("");
  const [crop, setCrop] = useState<Crop>();
  const [completedCrop, setCompletedCrop] = useState<PixelCrop>();
  const [scale, setScale] = useState(1);
  const [rotate, setRotate] = useState(0);
  const [aspect, setAspect] = useState<number | undefined>();

  function onSelectFile(e: React.ChangeEvent<HTMLInputElement>) {
    if (e.target.files && e.target.files.length > 0) {
      setCrop(undefined); // Makes crop preview update between images.
      const reader = new FileReader();
      reader.addEventListener('load', () =>
        setImgSrc(reader.result?.toString() || ''),
      );
      reader.readAsDataURL(e.target.files[0]);
    }
  }

  function onImageLoad(e: React.SyntheticEvent<HTMLImageElement>) {
    if (aspect) {
      const { width, height } = e.currentTarget;
      setCrop(centerAspectCrop(width, height, aspect));
    }
  }

  async function onDownloadCropClick() {
    const image = imgRef.current;
    const previewCanvas = previewCanvasRef.current;
    if (!image || !previewCanvas || !completedCrop) {
      throw new Error('Crop canvas does not exist');
    }

    // This will size relative to the uploaded image
    // size. If you want to size according to what they
    // are looking at on screen, remove scaleX + scaleY
    const scaleX = image.naturalWidth / image.width;
    const scaleY = image.naturalHeight / image.height;

    const offscreen = new OffscreenCanvas(
      completedCrop.width * scaleX,
      completedCrop.height * scaleY,
    );
    const ctx = offscreen.getContext('2d');
    if (!ctx) {
      throw new Error('No 2d context');
    }

    ctx.drawImage(
      previewCanvas,
      0,
      0,
      previewCanvas.width,
      previewCanvas.height,
      0,
      0,
      offscreen.width,
      offscreen.height,
    );
    // const dataurl = offscreen.convertToBlob;
    // You might want { type: "image/jpeg", quality: <0 to 1> } to
    // reduce image size
    const blob = await offscreen.convertToBlob({
      type: 'image/png',
    });

    const dataUrl = await new Promise<string>((resolve, reject) => {
      const reader = new FileReader();
      reader.onloadend = () => resolve(reader.result as string);
      reader.onerror = reject;
      reader.readAsDataURL(blob);
    });
    onOk(dataUrl, blob);
    setShow(false);
    // if (blobUrlRef.current) {
    //   URL.revokeObjectURL(blobUrlRef.current);
    // }
    // blobUrlRef.current = URL.createObjectURL(blob);

    // if (hiddenAnchorRef.current) {
    //   hiddenAnchorRef.current.href = blobUrlRef.current;
    //   hiddenAnchorRef.current.click();
    // }
  }

  useDebounceEffect(
    async () => {
      if (
        completedCrop?.width &&
        completedCrop?.height &&
        imgRef.current &&
        previewCanvasRef.current
      ) {
        // We use canvasPreview as it's much faster than imgPreview.
        canvasPreview(
          imgRef.current,
          previewCanvasRef.current,
          completedCrop,
          scale,
          rotate,
        );
      }
    },
    100,
    [completedCrop, scale, rotate],
  );
  const reset = () => {
    setCrop(undefined);
    setCompletedCrop(undefined);
    setScale(1);
    setRotate(0);
    setAspect(undefined);
    // setAspect(16 / 9);

    if (imgRef.current) {
      const { width, height } = imgRef.current;
      const newCrop = centerAspectCrop(width, height, 16 / 9);
      setCrop(newCrop);
      // Updates the preview
      setCompletedCrop(convertToPixelCrop(newCrop, width, height));
    }
  };
  // function handleToggleAspectClick() {
  //   if (aspect) {
  //     setAspect(undefined);
  //   } else {
  //     setAspect(16 / 9);

  //     if (imgRef.current) {
  //       const { width, height } = imgRef.current;
  //       const newCrop = centerAspectCrop(width, height, 16 / 9);
  //       setCrop(newCrop);
  //       // Updates the preview
  //       setCompletedCrop(convertToPixelCrop(newCrop, width, height));
  //     }
  //   }
  // }
  const fileInput = useId();
  return (
    <>
      <Button
        loading={uploading}
        icon={<UploadOutlined />}
        onClick={() => {
          setShow(true);
          setRandom(Math.random());
          setImgSrc('');
        }}
      >
        上传
      </Button>
      {show ? (
        <Modal
          title="图片裁剪"
          maskClosable={false}
          open={show}
          onCancel={() => setShow(false)}
          width={1000}
          height={800}
          okButtonProps={{
            disabled: !completedCrop?.width || !completedCrop?.height,
          }}
          onOk={() => {
            onDownloadCropClick();
          }}
        >
          <div className={styles.wrap} key={random}>
            <Row gutter={[gutter, gutter]}>
              <Col span={24}>
                <Row gutter={[gutter, gutter]}>
                  <Col span={14}>
                    <div className={styles.area}>
                      {!!imgSrc && (
                        <ReactCrop
                          crop={crop}
                          onChange={(_, percentCrop) => setCrop(percentCrop)}
                          onComplete={(c) => setCompletedCrop(c)}
                          aspect={aspect}
                          // maxWidth={300}
                          // maxHeight={300}
                          // minWidth={400}
                          // minHeight={100}
                          // circularCrop
                        >
                          <img
                            ref={imgRef}
                            alt="Crop me"
                            src={imgSrc}
                            style={{
                              transform: `scale(${scale}) rotate(${rotate}deg)`,
                            }}
                            onLoad={onImageLoad}
                          />
                        </ReactCrop>
                      )}
                    </div>
                  </Col>
                  <Col span={10}>
                    <Row gutter={[gutter, gutter]}>
                      <Col span={24}>
                        <strong>调整选项</strong>
                      </Col>
                      <Col span={24}>
                        <Radio.Group
                          optionType="button"
                          buttonStyle="solid"
                          value={aspect}
                          onChange={(e) => {
                            var val = e.target.value;
                            setAspect(val);
                            if (imgRef.current) {
                              const { width, height } = imgRef.current;
                              const newCrop = centerAspectCrop(
                                width,
                                height,
                                val || 16 / 9,
                              );
                              setCrop(newCrop);
                              // Updates the preview
                              setCompletedCrop(
                                convertToPixelCrop(newCrop, width, height),
                              );
                            }
                          }}
                          options={[
                            // 自由
                            {
                              label: '自由比例',
                              value: undefined,
                            },
                            {
                              label: '1/1',
                              value: 1 / 1,
                            },
                            // 3:2
                            {
                              label: '3/2',
                              value: 3 / 2,
                            },
                            //4:3
                            {
                              label: '4/3',
                              value: 4 / 3,
                            },
                            //3:4
                            {
                              label: '3/4',
                              value: 3 / 4,
                            },
                            // 19/ 6
                            {
                              label: '16/9',
                              value: 16 / 9,
                            },
                          ]}
                        />
                      </Col>
                      <Col span={24}>
                        <strong>绽放 {scale}</strong>
                      </Col>
                      <Col span={24}>
                        <Slider
                          min={0}
                          max={3}
                          defaultValue={1}
                          step={0.1}
                          value={scale}
                          onChange={setScale}
                        />
                      </Col>
                      <Col span={24}>
                        <strong>旋转角度 {rotate}</strong>
                      </Col>
                      <Col span={24}>
                        <Slider
                          min={-360}
                          max={360}
                          value={rotate}
                          onChange={setRotate}
                        />
                      </Col>
                      <Col span={24}>
                        <strong>图片预览</strong>
                      </Col>
                      <Col span={24}>
                        <div className={styles.preview}>
                          {!!completedCrop && (
                            <canvas
                              ref={previewCanvasRef}
                              style={{
                                objectFit: 'contain',
                                width: 365,
                                height: 280,
                              }}
                            />
                          )}
                        </div>

                        {/* <div style={{ fontSize: 12, color: "#666" }}>
                            If you get a security error when downloading try
                            opening the Preview in a new tab (icon near top
                            right).
                          </div> */}
                        <a
                          href="#hidden"
                          ref={hiddenAnchorRef}
                          download
                          style={{
                            position: 'absolute',
                            top: '-200vh',
                            visibility: 'hidden',
                          }}
                        >
                          Hidden download
                        </a>
                      </Col>
                    </Row>

                    <div className="Crop-Controls" hidden>
                      <input
                        ref={(file) => {
                          fileRef.current = file;
                        }}
                        id={fileInput}
                        type="file"
                        accept="image/*"
                        onChange={onSelectFile}
                      />
                    </div>
                  </Col>
                </Row>
              </Col>
              <Col span={24}>
                <Row gutter={[gutter, gutter]}>
                  <Col span={14}>
                    <Row justify={'end'} gutter={[gutter, gutter]}>
                      <Col>
                        <Button size="small" onClick={reset}>
                          重置
                        </Button>
                      </Col>
                      <Col>
                        <Button
                          type="primary"
                          ghost
                          size="small"
                          onClick={() => fileRef.current?.click()}
                        >
                          选择图片
                        </Button>
                      </Col>
                    </Row>
                  </Col>
                  <Col span={10}>
                    <Row justify={'end'}>
                      <Col>
                        {' '}
                        <Button
                          hidden
                          type="primary"
                          disabled={
                            !completedCrop?.width || !completedCrop?.height
                          }
                          onClick={onDownloadCropClick}
                        >
                          确定
                        </Button>
                      </Col>
                    </Row>
                  </Col>
                </Row>
              </Col>
            </Row>
          </div>
        </Modal>
      ) : null}
    </>
  );
}
